# 第十周


# 1. 集合（set）元素去重的判断依据是什么

# 2. 总结本周视频讲解魔术方法的作用及什么情况会执行到该方法

# 3. 结合本周所学内容，实现如下类：

#    ```python
#    class Ob:
#      pass
   
#    执行以下操作：
#    a = Ob('tom')
#    b = Ob('tom')
#    print('a: ', a)
#    a[0] = 'a'
#    print('a:', a)
#    a * 3
#    print('len: ', len(a))
#    del a[1]
#    print('a: ', a)
#    print('set: ', {a, b})
   
#    其输出如下：
#    a: ['1', '2']
#    a: ['a', '2']
#    len:  6
#    a: ['a', 'a', '2', 'a', '2']
#    set: {<Ob name=tom items=['a', 'a', '2', 'a', '2']>}




# 1
# 集合去重的依据是元素的哈希值相等,并且等值比较结果为True

# 2
# 魔术方法可实现一些灵巧的调用形式，
# 例如：获取对象长度、可迭代、可索引、设置索引、数值运算符的重载、可调用、可哈希、
# 逻辑运算符的重载、类型转换的实现等。
# 
# 例如：实现了__len__方法，就可以用len函数调用实例对象，如len(obj)
# 实现了__getitem__方法，就可以对实例进行索引调用，如obj[2]
# 实现了__setitem__方法，就可以对实例进行索引赋值，如obj[2]=10
# 实现了__call__方法，那么实例也可以被“调用”，obj()
# 实现了__eq__方法，那么实例也可以执行“==”运算符，如obj==9

# 3

class Ob:
    def __init__(self,name='tom') -> None:
        self.name=name
        self.items=['1','2']


    def __len__(self):
        return len(self.items)
    
    def __str__(self) -> str:
        return str(self.items)

    def __repr__(self) -> str:
        return "Ob name={} item={}".format(
            self.name,
            str(self.items)
        )

    def __getitem__(self,index):
        return self.items[index]

    def __setitem__(self,index,value):
        self.items[index]=value

    def __mul__(self,value):
        self.items=self.items*value

    def __delitem__(self,index):
        del self.items[index]

    def __hash__(self):
        return hash(self.name)

    # 必须等值比较
    def __eq__(self, __o: object) -> bool:
        return self.name==__o.name

# 执行以下操作：
a = Ob('tom')
b = Ob('tom')

print('a: ', a)
a[0] = 'a'
print('a:', a)
a * 3
print('len: ', len(a))
del a[1]
print('a: ', a)

print('set: ', {a, b})




